package frsf.cidisi.exercise.tp1_ia.search;

import frsf.cidisi.faia.agent.Perception;
import frsf.cidisi.faia.agent.search.SearchBasedAgentState;

/**
 * Represent the internal state of the Agent.
 */
public class EstadoAgente extends SearchBasedAgentState {
	
	public static int INITIAL= 0;
	public static int FORECAST_REQUEST_SENT = 1;
	public static int FORECAST_REQUEST_AGREE = 2;
	public static int FORECAST_REQUEST_REFUSE = 3;
	public static int INFORM_PLANNED_EVENTS_SENT = 4;
	public static int INFORM_POS_FORECAST_SENT = 5;
	public static int PROPOSE_DEMAND_FORECAST_1 = 6;
	public static int DEMAND_FORECAST_RESPONSE = 7;
	public static int ACCEPT_PROPOSAL_SENT = 8;
	public static int UPDATED_DEMAND_FORECAST_SENT = 9;
	public static int SUCCESS = 10;
	public static int PROPOSE_DEMAND_FORECAST_2 = 11;
	public static int SUBPROCESS_3_FINALIZED = 12;
	
	
	//TODO: Setup Variables
    private int tpoTranscurrido;
    private int diasEsperando;
    private int posicionAgente;
    
    private String perceptionName;
    private int perceptionTime;
	

    public EstadoAgente() {
    
    	perceptionName ="Waiting Request";
		tpoTranscurrido = 0;
		diasEsperando = 0;
		posicionAgente = EstadoAgente.INITIAL;
		perceptionTime = 0;    
        this.initState();
    }

    public EstadoAgente(int tpo, int dias, int pos, String pName, int pTime) {
		
    	tpoTranscurrido = tpo;
    	diasEsperando = dias;
    	posicionAgente = pos;
    	perceptionName = pName;
    	perceptionTime = pTime;
    	
	}

	/**
     * This method clones the state of the agent. It's used in the search
     * process, when creating the search tree.
     */
    @Override
    public SearchBasedAgentState clone() {
        
		int tpo = tpoTranscurrido;
    	int dias = diasEsperando;
    	int pos = posicionAgente;
    	String pName = perceptionName;
    	int pTime = perceptionTime;   	
    	
        return new EstadoAgente(tpo,dias,pos,pName,pTime);
    }

    /**
     * This method is used to update the Agent State when a Perception is
     * received by the Simulator.
     */
    @Override
    public void updateState(Perception p) {
        
       	ComputersMarketPerception per = (ComputersMarketPerception) p; 
    	
    	if(per.getwaiting_request() != 0 ){
    		
    		perceptionName = "Waiting for Request";
    		perceptionTime = per.getTiempo();
    		
    	} else if(per.getagree_forecastrequestresponse() != 0){
    		
    		perceptionName = "Agree Forecast Request";
    		perceptionTime = per.getTiempo();
    		
    	} else if(per.getrefuse_forecastrequestresponse() != 0){
    		
    		perceptionName = "Refuse Forecast Request";
    		perceptionTime = per.getTiempo();
    		
    	} else if(per.getpropose_demandforecast1() != 0){
    		
    		perceptionName = "Propose Demand Forecast1";
    		perceptionTime = per.getTiempo();
    		
    	} else if(per.getcancel_demandforecast() != 0){
    		
    		perceptionName = "Cancel Demand Forecast";
    		perceptionTime = per.getTiempo();
    		
    	} else if(per.getpropose_demandforecast2() != 0){
    		
    		perceptionName = "Propose Demand Forecast2";
    		perceptionTime = per.getTiempo();
    		
    	} else if(per.getinform_issues() !=0 ){
    		
    		perceptionName = "Inform Issues";
    		perceptionTime = per.getTiempo();    		
    	
    	}
    	
    	
    }

    /**
     * This method is optional, and sets the initial state of the agent.
     */
    @Override
    public void initState() {
    	perceptionName ="Waiting Request";
		tpoTranscurrido = 0;
		diasEsperando = 0;
		posicionAgente = EstadoAgente.INITIAL;
		perceptionTime = 0;
    }

    /**
     * This method returns the String representation of the agent state.
     */
    @Override
    public String toString() {
        StringBuffer str = new StringBuffer();

        str.append("Posicion: ");
        str.append(this.getposicionAgente());
        str.append(" | Tiempo Transcurrido: ");
        str.append(this.gettpoTranscurrido());
        str.append(" | Perception: ");
        str.append(this.getPerceptionName());
        str.append(" | Tiempo Respuesta: ");
        str.append(this.getPerceptionTime());
        str.append(" | Dias Esperando: ");
        str.append(this.getdiasEsperando());
        
        return str.toString();
    }

    /**
     * This method is used in the search process to verify if the node already
     * exists in the actual search.
     */
    @Override
    public boolean equals(Object obj) {
       
    	EstadoAgente temp;
    	
    	if(obj != null && obj instanceof EstadoAgente){
    		
    		temp = (EstadoAgente) obj;
    		
    		if(this.diasEsperando == temp.getdiasEsperando()
    				&& this.perceptionName.equals(temp.getPerceptionName())
    				&& this.perceptionTime == temp.perceptionTime
    				&& this.posicionAgente == temp.getposicionAgente()
    				&& this.tpoTranscurrido == temp.getposicionAgente()){
    			
    			return true; 
    		}
    		
    	}
    	   
    	return false;
    }

    //TODO: Complete this section with agent-specific methods
    // The following methods are agent-specific:
   	
     public int gettpoTranscurrido(){
        return tpoTranscurrido;
     }
     public void settpoTranscurrido(int arg){
        tpoTranscurrido += arg;
     }
     public int getdiasEsperando(){
        return diasEsperando;
     }
     public void setdiasEsperando(int arg){
        diasEsperando += arg;
     }
     public int getposicionAgente(){
        return posicionAgente;
     }
     public void setposicionAgente(int arg){
        posicionAgente = arg;
     }

	public String getPerceptionName() {
		return perceptionName;
	}

	public void setPerceptionName(String perceptionName) {
		this.perceptionName = perceptionName;
	}

	public int getPerceptionTime() {
		return perceptionTime;
	}

	public void setPerceptionTime(int perceptionTime) {
		this.perceptionTime = perceptionTime;
	}

	public boolean isCanceled() {
		if(perceptionName.equals("Refuse Forecast Request")){
			return true;
		}
		return false;
	}  
	
}

